﻿using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Text;
using System;

namespace Miao.Editor
{
    public class NamespaceRenameTool : EditorWindow
    {
        private enum ProcessingMode
        {
            RenameNamespace,
            AddNamespace
        }

        private ProcessingMode mode = ProcessingMode.RenameNamespace;
        private string originalNamespace = "";
        private string newNamespace = "";
        private string targetPath = "";
        private bool dryRun = true;
        private Vector2 logScrollPosition;
        private List<string> logMessages = new List<string>();

        [MenuItem("Miao/Tools/命名空间批量重命名工具")]
        public static void ShowWindow()
        {
            GetWindow<NamespaceRenameTool>("命名空间批量重命名工具");
        }

        private void OnGUI()
        {
            GUILayout.Label("命名空间批量处理工具", EditorStyles.boldLabel);

            EditorGUILayout.Space();

            mode = (ProcessingMode)EditorGUILayout.EnumPopup("操作模式", mode);

            EditorGUILayout.Space();

            if (mode == ProcessingMode.RenameNamespace)
            {
                originalNamespace = EditorGUILayout.TextField("原命名空间", originalNamespace);
            }

            newNamespace = EditorGUILayout.TextField("目标命名空间", newNamespace);

            EditorGUILayout.Space();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("目标路径（请通过浏览更改）");
            GUILayout.TextField(targetPath, EditorStyles.textField, GUILayout.ExpandWidth(true));

            if (GUILayout.Button("浏览...", GUILayout.Width(60)))
            {
                string selectedPath = EditorUtility.OpenFolderPanel("选择目录", Application.dataPath, "");
                if (!string.IsNullOrEmpty(selectedPath) && selectedPath.StartsWith(Application.dataPath))
                {
                    targetPath = "Assets" + selectedPath.Substring(Application.dataPath.Length);
                }
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Space();

            dryRun = EditorGUILayout.Toggle("仅预览（不执行修改）", dryRun);

            EditorGUILayout.Space();

            if (GUILayout.Button("执行操作"))
            {
               
                ProcessFiles();
            }

            EditorGUILayout.Space();

            GUILayout.Label("操作日志:", EditorStyles.boldLabel);
            logScrollPosition = EditorGUILayout.BeginScrollView(logScrollPosition);

            foreach (var message in logMessages)
            {
                EditorGUILayout.LabelField(message);
            }

            EditorGUILayout.EndScrollView();
        }

        private void ProcessFiles()
        {
            string fullPath = null;
            if (targetPath == "Assets")
            {
                fullPath = Application.dataPath;
            }
            else
            {
                fullPath = Path.Combine(Application.dataPath, targetPath.Replace("Assets/", ""));
            }
            if (!Directory.Exists(fullPath))
            {
                EditorUtility.DisplayDialog("错误", "指定的路径不存在: " + targetPath, "确定");
                return;
            }


            logMessages.Clear();
            logMessages.Add($"开始执行操作: {mode}");
            logMessages.Add(dryRun ? "【仅预览模式】不会执行实际修改" : "【执行模式】将修改文件内容");
            logMessages.Add("目标命名空间: " + newNamespace);
            logMessages.Add("目标路径: " + targetPath);
            logMessages.Add("");

            // 获取指定路径下的所有C#文件
            string[] allFiles = Directory.GetFiles(fullPath, "*.cs", SearchOption.AllDirectories);
            int processedFilesCount = 0;

            foreach (string filePath in allFiles)
            {
                try
                {
                    string fileContent = File.ReadAllText(filePath);
                    string newContent = fileContent;
                    bool fileModified = false;

                    if (mode == ProcessingMode.RenameNamespace)
                    {

                        // 删除旧的using语句
                        string oldUsingPattern = @"using\s+" + Regex.Escape(originalNamespace) + @";";
                        string newUsingPattern = @"using\s+" + Regex.Escape(newNamespace) + @";";
                        Match oldMatch = Regex.Match(fileContent, oldUsingPattern);
                        if (oldMatch.Success)
                        {
                            Match newMatch = Regex.Match(fileContent, newUsingPattern);
                            //查找是否包含已包含匹配符
                            if (newMatch.Success)
                            {
                                newContent = Regex.Replace(newContent, oldMatch.Value, "");
                              
                            }
                            else
                            {
                                //不包含则添加通用using
                                newContent = Regex.Replace(newContent, oldMatch.Value, @"using " + newNamespace + @";");
                            }
                            fileModified = true;
                            logMessages.Add($"找到文件: {GetRelativePath(filePath)}");
                            if (!dryRun)
                            {
                                logMessages.Add($"  已处理using语句");
                            }
                            else
                            {
                                logMessages.Add($"  预览using语句（未保存）");
                            }
                        }
                        // 处理using别名语句
                        string oldUsingAliasPattern = @"using\s+(\w+)\s*=\s*" + Regex.Escape(originalNamespace) + @"(\.\w+)*;";
                        MatchCollection oldUsingAliasMatches = Regex.Matches(fileContent, oldUsingAliasPattern);
                        foreach (Match oldUsingAliasMatch in oldUsingAliasMatches)
                        {
                            string alias = oldUsingAliasMatch.Groups[1].Value;
                            string newUsingAlias = $"using {alias} = {newNamespace}.{alias};";

                            newContent = newContent.Replace(oldUsingAliasMatch.Value, newUsingAlias);
                            fileModified = true;
                            logMessages.Add($"找到文件: {GetRelativePath(filePath)}");
                            if (!dryRun)
                            {
                                logMessages.Add($"  已处理using别名语句");
                            }
                            else
                            {
                                logMessages.Add($"  预览using别名语句（未保存）");
                            }
                        }


                        // 用于匹配命名空间声明的正则表达式
                        string pattern = @"(?<=\bnamespace\s+)" + Regex.Escape(originalNamespace);
                        Match matches = Regex.Match(fileContent, pattern);
                        if (matches.Success)
                        {
                            // 替换命名空间
                            newContent = Regex.Replace(fileContent, pattern, newNamespace);
                            fileModified = true;
                            logMessages.Add($"找到文件: {GetRelativePath(filePath)}");
                            if (!dryRun)
                            {
                                logMessages.Add($"  已重命名命名空间");
                            }
                            else
                            {
                                logMessages.Add($"  预览重命名（未保存）");
                            }
                        }

                        if(fileModified)
                        {
                            if (!dryRun)
                            {
                                File.WriteAllText(filePath, newContent,Encoding.UTF8);
                            }
                               
                        }

                    }
                    else if (mode == ProcessingMode.AddNamespace)
                    {
                        // 检查文件是否已经有命名空间
                        if (!Regex.IsMatch(fileContent, @"^\s*namespace\s+\w+", RegexOptions.Multiline))
                        {
                            // 检查文件是否包含类/接口/结构体定义
                            if (Regex.IsMatch(fileContent, @"(class|interface|struct)\s+\w+"))
                            {
                                logMessages.Add($"找到文件: {GetRelativePath(filePath)}");

                                // 在文件开头添加命名空间
                                newContent = $@"namespace {newNamespace}
{{
{fileContent}
}}";
                                fileModified = true;

                                if (!dryRun)
                                {
                                    File.WriteAllText(filePath, newContent);
                                    logMessages.Add($"  已添加命名空间");
                                }
                                else
                                {
                                    logMessages.Add($"  预览添加（未保存）");
                                }
                            }
                        }
                    }

                    if (fileModified)
                    {
                        processedFilesCount++;
                        logMessages.Add("");
                    }
                }
                catch (System.Exception e)
                {
                    logMessages.Add($"处理文件 {GetRelativePath(filePath)} 时出错: {e.Message}");
                    logMessages.Add("");
                }
            }

            logMessages.Add($"操作完成！共扫描 {allFiles.Length} 个文件，处理了 {processedFilesCount} 个文件。");

            // 刷新项目视图
            if (!dryRun && processedFilesCount > 0)
            {
                AssetDatabase.Refresh();
            }
        }

        // 辅助方法：找到字符串中第一个非空白字符的索引
        private int IndexOfFirstNonWhitespace(string str)
        {
            for (int i = 0; i < str.Length; i++)
            {
                if (!char.IsWhiteSpace(str[i]))
                {
                    return i;
                }
            }
            return -1;
        }

        private string GetRelativePath(string absolutePath)
        {
            return absolutePath.Replace(Application.dataPath, "Assets");
        }
    }
}